#include "algorithm"
#include "iostream"
#include "random"
#include "vector"

using std::find;
using std::reverse;
using std::shuffle;
using std::string;
using std::unique;
using std::vector;

struct Person {
  string name;
  int age;
};

int main() {
  // 创建 vector
  vector<int> v{1, 1, 2, 2, 3, 4, 5};
  auto p = find(v.begin(), v.end(), 3);
  if (p != v.end()) {
    std::cout << "found" << std::endl;
  }

  // 反转 vector
  std::cout << "reverse ==> " << std::endl;
  reverse(v.begin(), v.end());
  for (auto i : v) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  // shuffle
  std::cout << "shuffle ==> " << std::endl;
  std::mt19937 rng(std::random_device{}());
  shuffle(v.begin(), v.end(), rng);
  for (auto i : v) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  // sort // default cmp
  std::cout << "sort ==> " << std::endl;
  std::sort(v.begin(), v.end());
  for (auto i : v) {
    std::cout << i << " ";
  }
  std::cout << std::endl;
  // sort // self cmp
  std::cout << "sort self cmp ==> " << std::endl;
  std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
  for (auto i : v) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  // stable sort
  std::stable_sort(v.begin(), v.end());
  std::cout << "stable sort ==> " << std::endl;
  for (auto i : v) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  // partial sum
  vector<int> src = {1, 2, 3, 4, 5};
  vector<int> dst;
  // 求解src中元素的前缀和，dst[i] = src[0] + ... + src[i]
  // back_inserter 函数作用在 dst 容器上，提供一个迭代器
  partial_sum(src.begin(), src.end(), back_inserter(dst));
  for (int i : dst) {
    std::cout << i << " ";
  }

  // person
  vector<Person> persons;
  persons.push_back({"zhangsan", 20});
  persons.push_back({"lisi", 30});
  persons.push_back({"wangwu", 40});
  persons.push_back({"zhaoliu", 50});
  persons.push_back({"tianqi", 60});
  // sort
  std::cout << "sort person ==> " << std::endl;
  std::sort(persons.begin(), persons.end(),
            [](const Person &a, const Person &b) { return a.age < b.age; });
  for (auto &p : persons) {
    std::cout << p.name << " " << p.age << std::endl;
  }
  std::cout << std::endl;

  // sort person by name
  std::cout << "sort person ==> " << std::endl;
  std::sort(persons.begin(), persons.end(),
            [](const Person &a, const Person &b) { return a.name < b.name; });
  for (auto &p : persons) {
    std::cout << p.name << " " << p.age << std::endl;
  }
  std::cout << std::endl;

  return 0;
}
